package com.guocheng.utils;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.AbstractWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.guocheng.modules.emp.model.po.Emp;
import com.guocheng.modules.login.model.po.User;

import java.lang.reflect.Field;
import java.util.Date;
import java.util.Map;
import java.util.Set;

public class WrapperUtils {

    /**
     * 将实体类转换为Wrapper,通过反射
     *
     * @param t 要转换的实体类
     * @return
     */
    public static <T> QueryWrapper<T> modelToQueryWrapper(T t) {
        return (QueryWrapper<T>) wrapper(new QueryWrapper<T>(), t, true);
    }

    /**
     * 将实体类转换为Wrapper,通过反射
     *
     * @param t       要转换的实体类
     * @param isTield 是否过滤TableField接口
     * @return
     */
    public static <T> QueryWrapper<T> modelToQueryWrapper(T t, boolean isTield) {
        return (QueryWrapper<T>) wrapper(new QueryWrapper<T>(), t, isTield);
    }

    /**
     * 将实体类转换为Wrapper,通过反射
     *
     * @param t 要转换的实体类
     * @return
     */
    public static <T> UpdateWrapper<T> modelToUpdateWrapper(T t) {
        return (UpdateWrapper<T>) wrapper(new UpdateWrapper<T>(), t, true);
    }

    /**
     * 将实体类转换为Wrapper,通过反射
     *
     * @param t       要转换的实体类
     * @param isTield 是否过滤TableField接口
     * @return
     */
    public static <T> UpdateWrapper<T> modelToUpdateWrapper(T t, boolean isTield) {
        return (UpdateWrapper<T>) wrapper(new UpdateWrapper<T>(), t, isTield);
    }

    /**
     * 将map转换为Wrapper
     *
     * @param map 要转换的map
     * @return
     */
    public static <T> QueryWrapper<T> mapToQueryWrapper(QueryWrapper<T> queryWrapper, Map map) {
        return (QueryWrapper<T>) wrapper(queryWrapper, map);
    }

    /**
     * 将map转换为Wrapper
     *
     * @param map 要转换的map
     * @return
     */
    public static <T> UpdateWrapper<T> mapToUpdateWrapper(UpdateWrapper<T> updateWrapper, Map map) {
        return (UpdateWrapper<T>) wrapper(updateWrapper, map);
    }

    /**
     * Wrapper添加条件
     *
     * @param queryWrapper 构造器
     * @param t            要转换的map
     * @return
     */
    public static <T> QueryWrapper<T> queryWrapperAdd(QueryWrapper<T> queryWrapper, Object t) {
        return (QueryWrapper<T>) wrapper(queryWrapper, t, true);
    }


    /**
     * Wrapper添加条件
     *
     * @param t            要转换的map
     * @param queryWrapper 构造器
     * @param isTield      是否过滤TableField接口
     * @return
     */
    public static <T> QueryWrapper<T> queryWrapperAdd(QueryWrapper<T> queryWrapper, Object t, boolean isTield) {
        return (QueryWrapper<T>) wrapper(queryWrapper, t, isTield);
    }

    /**
     * Wrapper添加条件
     *
     * @param updateWrapper 构造器
     * @param t             要转换的map
     * @return
     */
    public static <T> UpdateWrapper<T> updateWrapperAdd(UpdateWrapper<T> updateWrapper, Object t) {
        return (UpdateWrapper<T>) wrapper(updateWrapper, t, true);
    }

    /**
     * Wrapper添加条件
     *
     * @param t             要转换的map
     * @param updateWrapper 构造器
     * @param isTield       是否过滤TableField接口
     * @return
     */
    public static <T> UpdateWrapper<T> updateWrapperAdd(UpdateWrapper<T> updateWrapper, Object t, boolean isTield) {
        return (UpdateWrapper<T>) wrapper(updateWrapper, t, isTield);
    }


    /**
     * 将实体类转换为Wrapper,通过反射
     *
     * @param t       要转换的实体类
     * @param isTield false表示忽略TableField注解
     * @return
     * @Param wrapper 查询或者更新
     */
    private static AbstractWrapper wrapper(AbstractWrapper wrapper, Object t, boolean isTield) {
        if (t == null) return wrapper;
        //获得类的的属性名 数组
        Field[] fields = t.getClass().getDeclaredFields();
        try {
            for (Field field : fields) {
                field.setAccessible(true);
                //isTield表示判断需要TableField接口确定是否转换
                String name = isTableFileld(field, isTield);
                if (name == null) continue;
                ;
                //获取对象的姓名和值，放入hasmap中
                Object o = field.get(t);
                wrapper(wrapper, name, o);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return wrapper;
    }

    /**
     * 将map转换为Wrapper
     *
     * @param map 要转换的map
     * @return
     * @Param wrapper 查询或者更新
     */
    private static AbstractWrapper wrapper(AbstractWrapper wrapper, Map<String, Object> map) {
        if (map == null) return wrapper;
        Set<Map.Entry<String, Object>> maps = map.entrySet();
        for (Map.Entry<String, Object> entry : maps) {
            String key = entry.getKey();
            Object value = entry.getValue();
            wrapper(wrapper, key, value);
        }
        return wrapper;
    }

    /**
     * wrapper添加条件
     *
     * @param wrapper 要添加的构造器
     * @param name    名称（前方加‘like_’表示模糊查询,加'!_'表示不等于）
     * @param value   值
     */
    private static void wrapper(AbstractWrapper wrapper, String name, Object value) {
        if (value != null) {
            String name1 = LetterUtils.valTocamel(name, "_");
            if (value instanceof String) {
                String s = value.toString();
                chars chars = charIs(s);
                if (chars != null) {
                    switch (chars.lenght) {
                        case 2:     //!_
                            wrapper.ne(name1, chars.str);
                            return;
                        case 5:     //like
                            wrapper.like(name1, chars.str);
                            return;
                        case 6:     //!like
                            wrapper.notLike(name1, chars.str);
                            return;
                    }
                }
            }
            wrapper.eq(name1, value);
        }
    }

    /**
     * 是否需要TableField接口确定是否转换
     *
     * @param field   字段属性
     * @param isTield 是否需要
     * @return
     */
    private static String isTableFileld(Field field, boolean isTield) {
        if (!isTield) return field.getName();
        //下面的表示判断需要TableField接口确定是否转换
        TableField annotation = field.getAnnotation(TableField.class);
        String name = field.getName();
        if (annotation != null) {
            if (annotation.exist() && !annotation.value().equals("")) {
                return annotation.value();
            } else {
                return null;
            }
        }
        return name;
    }

    private final static char[] n1 = {'!', '_'};
    private final static char[] n2 = {'l', 'i', 'k', 'e', '_'};
    private final static char[] n3 = {'!', 'l', 'i', 'k', 'e', '_'};

    /**
     * char比较(0代表没有,2代表!_，5代表like_，6代表!like_)
     *
     * @param str
     * @return
     */
    private static chars charIs(String str) {
        char[] a = str.toCharArray();
        //如果总长小于3
        if (a.length < 2 || (a[0] != n1[0] && a[0] != n2[0])) return null;
        //先判断是否是n1
        if (a[0] == n1[0] && a[1] == n1[1]) return new chars(2, a);

        //如果总长大于5,则有可能为n3
        if (a.length > 6) {
            for (int i = 0; i < 6; i++) {
                if (a[i] != n3[i]) break;
                if (i == 5) return new chars(6, a);
            }
        }

        //如果总长大于5，则有可能是n2
        if (a.length > 5) {
            for (int i = 0; i < 5; i++) {
                if (a[i] != n2[i]) break;
                if (i == 4) return new chars(5, a);
            }
        }
        return null;
    }

    public static void main(String[] args) {
        Emp emp = new Emp();
        emp.setStatus(1).setName("!_sadas").setAvatar("like_dsada").setClassesId("!like_dsada").setClassessName("dsadas");
        QueryWrapper<Emp> empQueryWrapper = modelToQueryWrapper(emp);
        System.out.println(empQueryWrapper);
    }

    //返回对象
    private static class chars {
        chars(int lenght, char[] str) {
            this.lenght = lenght;
            this.str = new String(str, lenght, str.length - lenght);
        }

        int lenght;
        String str;
    }
}
